home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
docs
/
ippon
/
data
/
etc
/
lboss04.lzh
/
enemy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-20
|
10KB
|
436 lines
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <XSP2lib.H>
#include "main.h"
#include "enemy.h"
#include "fxsp2lib.h"
#include "parts.h"
#define SEQ_WING_ERASE 67
#define ENEMY_MAX 64 /* 最大数 */
static ENEMY enemy[ENEMY_MAX]; /* ワーク */
static ENEMY *enemy_top, /* 使用中のワークのリスト */
*enemy_null_top, /* 空のワークのリスト */
*enemy_end; /* 使用中ワークのリストの末尾 */
extern char end_of_data;
extern char f_option_flag;
typedef struct _spwork {
signed short x, y; /* 座標 */
unsigned short pt; /* スプライトパターンNo. */
unsigned short info; /* 反転コード・色・優先度を表わすデータ */
} SPWORK;
SPWORK spwork;
static FILE *fp_parts5,*fp_parts6;
int EnemyInit0 (void)
{
int i;
/* リストをつなげる */
enemy_top = NULL;
enemy_end = NULL;
enemy_null_top = enemy;
for (i = 0; i < ENEMY_MAX; i++)
enemy[i].next = &enemy[i + 1];
enemy[ENEMY_MAX - 1].next = NULL;
return(0);
}
void EnemyInit (unsigned short type, unsigned short info,
signed short ox, signed short oy, ENEMY * parent)
{
ENEMY *p;
if (enemy_null_top == NULL) {
printf ("ワークが一杯です\n");
return; /* 空きのワークがない(キャラクターオーバー) */
}
/* リストの末尾に新しいノードを追加 */
p = enemy_null_top;
enemy_null_top = p->next;
if (enemy_top == NULL)
enemy_top = p;
else
enemy_end->next = p;
p->next = NULL;
enemy_end = p;
p->type = type;
p->info = info;
p->ox = ox;
p->oy = oy;
p->x = p->y = 0;
p->parent = parent;
p->lx = p->ly = p->lz = 0.0;
p->vx = p->vy = p->vz = 0.0;
p->cyc = 0;
p->cyc1 = 0;
p->round = p->round_v = p->spring = p->spring_v = 0.0;
switch (p->type) {
case 1:
EnemyInit (3, 0x0437, -16 - 8, 0, p); /* 左翼(大) */
break;
case 2:
EnemyInit (4, 0x0437, 16 + 8, 0, p); /* 右翼(大) */
break;
case 5:
if (f_option_flag)
fp_parts5 = fopen ("parts5.doc", "w");
break;
case 6:
if (f_option_flag)
fp_parts6 = fopen ("parts6.doc", "w");
break;
default:
break;
}
}
/* 複数のスプライトで構成されているパーツ1個分のスプライトをまとめて表示 */
static void DispSp (ENEMY * p, short sp_num, PARTS_TABLE * parts_table)
{
short h;
for (h = 0; h < sp_num; h++) {
p->x = p->lx + p->ox;
p->y = p->ly + p->oy;
if (p->parent != NULL) {
spwork.x = p->x + p->parent->x + parts_table[h].x;
spwork.y = p->y + p->parent->y + parts_table[h].y;
} else {
spwork.x = p->x + parts_table[h].x;
spwork.y = p->y + parts_table[h].y;
}
spwork.pt = parts_table[h].pt;
spwork.info = p->info;
spwork.x += (128 + 16); /* 表示用に補正 */
spwork.y += (128 + 16);
xsp_set_st (&spwork);
fxsp_set_st (&spwork);
spwork.x -= (128 + 16);
spwork.y -= (128 + 16);
}
}
void EnemyMove (void)
{
ENEMY *p, *q;
p = enemy_top;
q = NULL;
while (p != NULL) {
char erase_flag = 0;
switch (p->type) {
case 0: /* 本体 */
DispSp (p, 48, parts0_table);
break;
case 1: /* 左翼(小) */
switch (p->cyc) {
#define R1 8 /* 半径 */
#define RA1 (0.02) /* 加速度 */
#define RV1_MAX (0.3) /* 速度最大値 */
case 0:/* 回転 */
p->round += p->round_v;
if ((p->round_v += RA1) > RV1_MAX)
p->round_v = RV1_MAX;
p->lx = R1 * cos (p->round);
p->ly = R1 * sin (p->round);
#define R1_MAX (M_PI)
if (p->round > R1_MAX) {
p->round -= R1_MAX;
p->cyc++;
}
break;
case 1:/* ばね振動 */
#define SPRING_K1 0.5
#define SPRING_M1 0.8 /* 摩擦計数 */
#define ROUND_MIN1 0.03 /* 座標がこれ以下になれば中断 */
#define ROUNDV_MIN1 0.10 /* 速度がこれ以下になれば中断 */
p->round += p->round_v;
p->round_v -= SPRING_K1 * p->round;
p->round_v *= SPRING_M1;
if ((fabs (p->round) < ROUND_MIN1) && (fabs (p->round_v) < ROUNDV_MIN1))
p->cyc++;
p->lx = R1 * cos (R1_MAX + p->round);
p->ly = R1 * sin (R1_MAX + p->round);
break;
case 2:
p->lx = R1 * cos (R1_MAX + p->round);
p->ly = R1 * sin (R1_MAX + p->round);
break;
default:
break;
}
DispSp (p, 25, parts1_table);
if (seq_counter == SEQ_WING_ERASE)
erase_flag = !0;
break;
case 2: /* 右翼(小) */
switch (p->cyc) {
case 0:/* 回転 */
p->round += p->round_v;
if ((p->round_v += RA1) > RV1_MAX)
p->round_v = RV1_MAX;
p->lx = -R1 * cos (p->round);
p->ly = R1 * sin (p->round);
if (p->round > R1_MAX) {
p->round -= R1_MAX;
p->cyc++;
}
break;
case 1:/* ばね振動 */
p->round += p->round_v;
p->round_v -= SPRING_K1 * p->round;
p->round_v *= SPRING_M1;
if ((fabs (p->round) < ROUND_MIN1) && (fabs (p->round_v) < ROUNDV_MIN1))
p->cyc++;
p->lx = -R1 * cos (R1_MAX + p->round);
p->ly = R1 * sin (R1_MAX + p->round);
break;
case 2:
p->lx = -R1 * cos (R1_MAX + p->round);
p->ly = R1 * sin (R1_MAX + p->round);
break;
default:
break;
}
DispSp (p, 25, parts2_table);
if (seq_counter == SEQ_WING_ERASE)
erase_flag = !0;
break;
case 3: /* 左翼(大) */
switch (p->cyc) {
#define R3 8 /* 半径 */
case 0:
p->lx = R3 * cos (p->round);
p->ly = R3 * sin (p->round);
if (seq_counter == 25)
p->cyc++;
break;
#define RA3 (0.02) /* 加速度 */
#define RV3_MAX (0.3) /* 速度最大値 */
case 1:/* 回転 */
p->round += p->round_v;
if ((p->round_v += RA3) > RV3_MAX)
p->round_v = RV3_MAX;
p->lx = R3 * cos (p->round);
p->ly = R3 * sin (p->round);
#define R3_MAX (M_PI)
if (p->round > R3_MAX) {
p->round -= R3_MAX;
p->cyc++;
}
break;
case 2:/* ばね振動 */
#define SPRING_K3 0.7
#define SPRING_M3 0.8 /* 摩擦計数 */
#define ROUND_MIN3 0.03 /* 座標がこれ以下になれば中断 */
#define ROUNDV_MIN3 0.03 /* 速度がこれ以下になれば中断 */
p->round += p->round_v;
p->round_v -= SPRING_K3 * p->round;
p->round_v *= SPRING_M3;
if ((fabs (p->round) < ROUND_MIN3) && (fabs (p->round_v) < ROUNDV_MIN3))
p->cyc++;
p->lx = R3 * cos (R3_MAX + p->round);
p->ly = R3 * sin (R3_MAX + p->round);
break;
default:
break;
}
DispSp (p, 42, parts3_table);
if (seq_counter == SEQ_WING_ERASE)
erase_flag = !0;
break;
case 4: /* 右翼(大) */
switch (p->cyc) {
case 0:
p->lx = -R3 * cos (p->round);
p->ly = R3 * sin (p->round);
if (seq_counter == 25)
p->cyc++;
break;
case 1:/* 回転 */
p->round += p->round_v;
if ((p->round_v += RA3) > RV3_MAX)
p->round_v = RV3_MAX;
p->lx = -R3 * cos (p->round);
p->ly = R3 * sin (p->round);
if (p->round > R3_MAX) {
p->round -= R3_MAX;
p->cyc++;
}
break;
case 2:/* ばね振動 */
p->round += p->round_v;
p->round_v -= SPRING_K3 * p->round;
p->round_v *= SPRING_M3;
if ((fabs (p->round) < ROUND_MIN3) && (fabs (p->round_v) < ROUNDV_MIN3))
p->cyc++;
p->lx = -R3 * cos (R3_MAX + p->round);
p->ly = R3 * sin (R3_MAX + p->round);
break;
default:
break;
}
DispSp (p, 42, parts4_table);
if (seq_counter == SEQ_WING_ERASE)
erase_flag = !0;
break;
case 5: /* 左耳 */
/* 2段階目左右翼パーツ */
#define P5_K 3.0 /* ばね定数(左右上小パーツ) */
#define P5_M 0.5 /* 摩擦計数(左右上小パーツ) */
#define P5_V 0.7 /* 速度がこれ以下なら次へ(左右上小パーツ) */
#define P5_L 0.7 /* 座標がこれ以下なら次へ(左右上小パーツ) */
switch (p->cyc) {
case 0:
p->vx -= 0.5;
if (p->vx < -3.0)
p->vx = -3.0;
p->lx += p->vx;
if (p->lx < -32.0){
p->lx += 32.0;
p->ox -= 32;
p->cyc++;
}
break;
case 1:/* ばね振動 */
p->vx -= p->lx * P5_K;
/* 摩擦 */
if (p->vx > 0)
p->vx -= P5_M;
else
p->vx += P5_M;
p->lx += p->vx;
if ((fabs (p->vx) < P5_V) && (fabs (p->lx) < P5_L)) {
p->cyc++; /* 次へ */
p->lx = 0.0;
p->ly = 0.0;
p->vx = 0.0;
p->vy = 0.0;
}
break;
case 2:
end_of_data = !0; /* debug */
break;
default:
break;
}
if (f_option_flag)
fprintf (fp_parts5, "{%d,%d}, ", (int) (p->lx + p->ox), (int) (p->ly + p->oy));
DispSp (p, 16, parts5_table);
break;
case 6: /* 右耳 */
switch (p->cyc) {
case 0:
p->vx += 0.5;
if (p->vx > 3.0)
p->vx = 3.0;
p->lx += p->vx;
if (p->lx > 32.0){
p->lx -= 32.0;
p->ox += 32;
p->cyc++;
}
break;
case 1:/* ばね振動 */
p->vx -= p->lx * P5_K;
/* 摩擦 */
if (p->vx > 0)
p->vx -= P5_M;
else
p->vx += P5_M;
p->lx += p->vx;
if ((fabs (p->vx) < P5_V) && (fabs (p->lx) < P5_L)) {
p->cyc++; /* 次へ */
p->lx = 0.0;
p->ly = 0.0;
p->vx = 0.0;
p->vy = 0.0;
}
break;
case 2:
end_of_data = !0; /* debug */
break;
default:
break;
}
if (f_option_flag)
fprintf (fp_parts6, "{%d,%d}, ", (int) (p->lx + p->ox), (int) (p->ly + p->oy));
DispSp (p, 16, parts6_table);
break;
default:
printf ("enemy_move() : バグってます\n");
break;
}
if (erase_flag) {
if (q == NULL) { /* リストの一番最初を削除 */
enemy_top = p->next;
p->next = enemy_null_top;
enemy_null_top = p;
q = NULL;
p = enemy_top;
} else {
if (p == enemy_end) { /* リストの一番最後を削除 */
q->next = NULL;
enemy_end = q;
p->next = enemy_null_top;
enemy_null_top = p;
p = q->next;
} else {
q->next = p->next;
p->next = enemy_null_top;
enemy_null_top = p;
p = q->next;
}
}
} else {
q = p;
p = p->next;
}
}
}
void EnemyTini (void)
{
int i;
/* リストをつなげる */
enemy_top = NULL;
enemy_null_top = enemy;
for (i = 0; i < ENEMY_MAX; i++)
enemy[i].next = &enemy[i + 1];
enemy[ENEMY_MAX - 1].next = NULL;
}